package com.wang.classloader;

import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 用户自定义类加载器，需覆盖findClass()
 */
public class CustomerClassLoader extends ClassLoader {
    /**
     * 自定义class文件的路径
     */
    private String classPath;

    public CustomerClassLoader(String classPath) {
        this.classPath = classPath;
    }


    /**
     * 重写findClass方法，解析class文件 =》 类定义
     *
     * @param name 包名 + 类名，如com.wang.Test
     * @return
     * @throws ClassNotFoundException
     */
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        // 类名
        String className = name.substring(name.lastIndexOf(".") + 1);
        // 找到class文件
        String path = classPath + File.separatorChar + className + ".class";
        try (InputStream in = new FileInputStream(path); ByteArrayOutputStream out = new ByteArrayOutputStream()) {
            byte[] buffer = new byte[2048];
            int len = 0;
            while ((len = in.read(buffer)) != -1) {
                out.write(buffer, 0, len);
            }
            // 解析class文件 =》 byte[]
            byte[] byteArray = out.toByteArray();
            // 调用defineClass()函数，将字节码转化为类定义
            return defineClass(name, byteArray, 0, byteArray.length);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 测试类
     */
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        // 加载工程外的class文件
        CustomerClassLoader customerClassLoader = new CustomerClassLoader("E:\\myself\\jvm-study\\nosrc");
        Class clazz = customerClassLoader.loadClass("wly.test.HaHa");
        // 获取实例对象
        Object o = clazz.newInstance();
        Method method = clazz.getMethod("sayHello", null);
        method.invoke(o, null);
        System.out.println(clazz.getClassLoader().toString());
    }
}
